package vue;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.CubicCurve2D;

import javax.swing.JPanel;

import modele.CKModel;
import modele.Concept;
import application.Consts;

public class PanelCK extends JPanel {

	static final long serialVersionUID = 12345;

	private CKModel<String, String> _modele;
	private VueEditeurCK _vue;

	public PanelCK(CKModel<String, String> modele) {
		this._modele = modele;
	}

	public PanelCK(CKModel<String, String> modele, VueEditeurCK vue) {
		this._modele = modele;
		this._vue = vue;
	}

	public void paint(Graphics g) {

		// TODO : S�parer et commenter le code. Faire en sorte que ce soit
		// plus facile � comprendre
		// Fonctions: drawC et drawK
		// Mettre toutes les constantes que tu utilise dans le code en
		// s�par�e avec celles du Haut + mettre en majuscule avec des noms
		// explicites.
		// Commenter le code pour guider le lecteur :-)
		g.drawLine(this.getWidth() / 2, 0, this.getWidth() / 2,
				this.getHeight());
		g.drawLine(0, 0, this.getWidth(), 0);
		g.drawString("Concept", this.getWidth() / 5, 20);
		g.drawString("Knowledge", (int) (this.getWidth() / 1.40), 20);
		this.setPreferredSize(new Dimension(_vue.getFrameWidth(), (2 * _vue
				.getFrameHeight()) / 3));

		int center = center(_modele.getCSpace());

		this.drawC(g, _modele, center);

		this.drawK(g, _modele);

		this.drawEdgeC(g, _modele.getCSpace(), center);

		this.drawCKlink((Graphics2D) g, _modele, center);

		g.dispose();
	}

	/**
	 * 
	 * @param g
	 * @param _modele
	 * @param center
	 */
	public void drawC(Graphics g, CKModel<String, String> _modele, int center) {

		for (int i = 0; i < _modele.getCSize(); i++) {
			g.drawOval(_modele.findConceptFromId(i).getPositionX() + center,
					_modele.findConceptFromId(i).getPositionY(),
					Consts.LARGEURELLIPSE, Consts.LONGUEURELLIPSE);
			g.drawString(_modele.findConceptFromId(i).getData(), _modele
					.findConceptFromId(i).getPositionX()
					+ center
					+ (Consts.LARGEURELLIPSE / 5), _modele.findConceptFromId(i)
					.getPositionY() + (2 * (Consts.LONGUEURELLIPSE / 3)));
		}
	}

	/**
	 * 
	 * @param g
	 * @param _modele
	 */
	public void drawK(Graphics g, CKModel<String, String> _modele) {
		// permet de définir l'espace que les rectangles vont occuper
		int espaceRectangle = 0;

		for (int i = 0; i < _modele.getKSpace().size(); i++) {

			if (_modele.getKSpace().elementAt(i).getDimension() != null) {

				espaceRectangle = espaceRectangle
						+ _modele.getKSpace().elementAt(i).getDimension().height;

			} else {

				espaceRectangle = espaceRectangle + 20;
				// set height in knowledge
				_modele.getKSpace().elementAt(i)
						.setDimension(new Dimension(0, 40));

			}
		}

		// permet de d�finir l'espace qui séparera chaque knowledge du
		// précédent et du suivant
		int espaceLibre = ((this.getHeight()) - espaceRectangle)
				/ (_modele.getKSpace().size() + 1);
		int pointY = espaceLibre + 20;

		for (int i = 0; i < _modele.getKSpace().size(); i++) {

			if (_modele.getKSpace().elementAt(i).getDimension() != null) {

				g.drawRect((this.getWidth() / 2) + 20, pointY, this.getWidth()
						- ((this.getWidth() / 2) + 40), _modele.getKSpace()
						.elementAt(i).getDimension().height);
				g.drawString(_modele.getKSpace().elementAt(i).getData(),
						(this.getWidth() / 2) + 30, pointY + 15);
				Point p = new Point((this.getWidth() / 2) + 20, pointY);
				_modele.getKSpace().elementAt(i).setPosition(p);
				pointY += espaceLibre
						+ _modele.getKSpace().elementAt(i).getDimension().height;

			} else {

				g.drawRect((this.getWidth() / 2) + 20, pointY, this.getWidth()
						- ((this.getWidth() / 2) + 40), 20);
				g.drawString(_modele.getKSpace().elementAt(i).getData(),
						(this.getWidth() / 2) + 30, pointY + 15);
				Point p = new Point((this.getWidth() / 2) + 20, pointY);
				_modele.getKSpace().elementAt(i).setPosition(p);
				pointY += espaceLibre + 20;
			}
		}
	}

	/**
	 * 
	 * @param c
	 * @return
	 */
	public int center(Concept<String> c) {
		return (this.getWidth() / 4)
				- (c.getPositionX() + (Consts.LARGEURELLIPSE / 2));
	}

	/**
	 * 
	 * @param g
	 * @param concept
	 * @param center
	 */
	public void drawEdgeC(Graphics g, Concept<String> concept, int center) {
		for (Concept<String> element : concept.getChildren()) {
			g.drawLine(concept.getPositionX() + center
					+ (Consts.LARGEURELLIPSE / 2), concept.getPositionY()
					+ Consts.LONGUEURELLIPSE, element.getPositionX() + center
					+ (Consts.LARGEURELLIPSE / 2), element.getPositionY());
			drawEdgeC(g, element, center);
		}
	}

	/**
	 * Draws the links between the two spaces
	 * 
	 * @param g
	 * @param _modele
	 * @param center
	 */
	public void drawCKlink(Graphics2D g, CKModel<String, String> _modele,
			int center) {
		for (int i = 0; i < _modele.getCSize(); i++) {
			for (int j = 0; j < _modele.getKSize(); j++) {
				System.out.println("i:" + i + " and j:" + j + " ="
						+ _modele.getCKLinks()[i][j] + _modele.getKSize());
				if (_modele.getCKLinks()[j][i] == true) { // test if link exists

					// Calculate end points for each side
					int ConceptXpos = _modele.findConceptFromId(i)
							.getPositionX() + center + Consts.LARGEURELLIPSE;
					int ConceptYpos = _modele.findConceptFromId(i)
							.getPositionY() + (Consts.LONGUEURELLIPSE / 2);
					int KnowledgeXpos = this.getWidth() / 2 + 20;
					int KnowledgeYpos = _modele.getKSpace().elementAt(j)
							.getPosition().y
							+ _modele.getKSpace().elementAt(j).getDimension().height
							/ 2;

					int BezierControlXpos = ConceptXpos
							+ (KnowledgeXpos - ConceptXpos) / 2;

					// create new CubicCurve2D.Double
					CubicCurve2D c = new CubicCurve2D.Double();
					// draw CubicCurve2D.Double with set coordinates
					c.setCurve(ConceptXpos, ConceptYpos, BezierControlXpos,
							ConceptYpos, BezierControlXpos, KnowledgeYpos,
							KnowledgeXpos, KnowledgeYpos);
					g.draw(c);
				}
			}
		}
	}

}
